import { _decorator, Camera, CCFloat, Component, EventTouch, Input, input, Node, PhysicsSystem2D, tween, v2, v3, Vec2, Vec3, view } from 'cc';

import WorldManager from './WorldManager';
import MapApi from '../api/MapApi';
import { UIManager } from './UIManager';
import { EventManager } from '../event/EventManager';
import { WorldController } from './WorldController';
import { Plane } from '../world/Plane';
import { EffectEnum, EffectManager } from './EffectManager';

const { ccclass, property } = _decorator;

@ccclass('WorldCamera')
export class WorldCamera extends Component {
    public static instance: WorldCamera;


    protected onLoad(): void {

        WorldCamera.instance = this

    }

    @property(CCFloat)
    public speed: number = 1;
    public camera: Camera;
    public center: Vec3 = v3(0, 0, 0);

    private startX: number = 0;
    private startY: number = 0;

    start() {
        this.camera = this.node.getComponent(Camera)
        // EventManager.instance.on(EventManager.EventType.PlaneTouchMove, this.onTouchMove, this)
        // EventManager.instance.on(EventManager.EventType.PlaneTouchEnd, this.onTouchEnd, this)
        // EventManager.instance.on(EventManager.EventType.PlaneTouchCancel, this.onTouchEnd, this)

        input.on(Input.EventType.TOUCH_START, this.onTouchStart, this)
        input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this)
        input.on(Input.EventType.TOUCH_END, this.onTouchEnd, this)
        input.on(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this)

    }

    protected onDisable(): void {
        // EventManager.instance.off(EventManager.EventType.PlaneTouchMove, this.onTouchMove, this)
        // EventManager.instance.off(EventManager.EventType.PlaneTouchEnd, this.onTouchEnd, this)
        // EventManager.instance.off(EventManager.EventType.PlaneTouchCancel, this.onTouchEnd, this)

        input.off(Input.EventType.TOUCH_START, this.onTouchStart, this)
        input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this)
        input.off(Input.EventType.TOUCH_END, this.onTouchEnd, this)
        input.off(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this)
    }

    onTouchStart(event: EventTouch) {
        this.startX = event.getLocationX()
        this.startY = event.getLocationY()

    }

    onTouchMove(event: EventTouch) {


        let touches = event.getAllTouches()
        if (touches.length == 1) {
            let pre = event.getPreviousLocation()
            let now = v2(event.getLocationX(), event.getLocationY())
            let offset = v2(0, 0)
            Vec2.subtract(offset, now, pre)

            this.speed = this.camera.orthoHeight * (1 / 480)
            this.node.translate(v3(- offset.x * this.speed, -offset.y * this.speed, 0))
        } else {
            let a = touches[0]
            let b = touches[1]
            let preDistance = Vec2.distance(a.getPreviousLocation(), b.getPreviousLocation())

            let nowDistance = Vec2.distance(a.getLocation(), b.getLocation())

            let orthoHeight = 0

            if (preDistance == nowDistance) {
                return
            }
            if (preDistance > nowDistance) {

                //放大
                orthoHeight = this.camera.orthoHeight + this.camera.orthoHeight * (10 / 700)
            } else {

                //缩小
                orthoHeight = this.camera.orthoHeight - this.camera.orthoHeight * (10 / 700)
            }

            if (orthoHeight < 480) {
                orthoHeight = 480
            }
            if (orthoHeight > 900) {
                orthoHeight = 900
            }
            this.camera.orthoHeight = orthoHeight
        }






    }

    onTouchEnd(event: EventTouch) {

       
        let touches = event.getAllTouches()
        if (touches.length > 0) {
            return
        }


        let x = event.getLocationX()
        let y = event.getLocationY()
        let distance = Vec2.distance(v2(this.startX, this.startY), v2(x, y))
        if (Math.abs(distance) < 10) {
            this.clickPlane(event)
            return
        }


        let pos = this.node.getPosition()
        let temp = v3(0, 0, 0)
        Vec3.subtract(temp, pos, this.center)
        let newTemp = WorldManager.instance.convertCoord(temp)
        x = newTemp.x
        y = newTemp.y
        
        let step = WorldManager.instance.step
        let sizeX = WorldManager.instance.sizeX
        let sizeY = WorldManager.instance.sizeY
        
        if (Math.abs(x / sizeX)  > step * 0.5 || Math.abs(y / sizeY) > step * 0.5) {
            this.loadMap()
        }

        
    }

    clickPlane(event: EventTouch) {
        let temp = v3(0, 0, 0)
        this.camera.screenToWorld(v3(event.getLocationX(), event.getLocationY(), 0), temp)

        const collider = PhysicsSystem2D.instance.testPoint(v2(temp.x, temp.y));


        // EffectManager.instance.playOnce(EffectEnum.ClickGround, temp)
        // EventManager.instance.emit(EventManager.EventType.HeroMove, temp)
        // return


        for (let c of collider) {
            c.node.getComponent(Plane)?.onClick()
        }

    }

    async loadMap() {
        let pos = this.node.position
       
        let newPos = WorldManager.instance.convertCoord(pos)
        let x = newPos.x
        let y = newPos.y
       
        let sizeX = WorldManager.instance.sizeX
        let sizeY = WorldManager.instance.sizeY
      
        x = Math.round(x / sizeX)
        y = Math.round(y / sizeY)
        
        console.log('loadMap:',x, ':', y)

        WorldController.instance.goZone(x, y, false)
        await UIManager.instance.showLoading()

    }

   

}


